
#include "Util.h"
#include "SemanticParser.h"
#include <string.h>
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>

void SemanticParser::SetBaseUrl(string url)
{
	mBaseUrl = url;
}

void SemanticParser::SetTimeOut(size_t timeOut)
{
	mTimeOut = timeOut;
}

string Encode(const string& str)
{
	string utf16Str;
	size_t codeLen = 3 * str.size();
	char buff[codeLen+1];
	memset(buff, 0, sizeof(buff));
	for (size_t i =0; i < str.size(); ++i)
	{
		size_t buffIndex = 3 * i; 
		sprintf(buff+buffIndex, "%%%02x", *((unsigned char*)(str.c_str()+i)) );
	}

	utf16Str = buff;
	return utf16Str;
}

string SemanticParser::SemanticParsing(const string& key, const string imei)
{
	string strEncodeKey = Encode(key);
	string url = mBaseUrl + "?t=" + strEncodeKey + "&i=" + imei;
	LOG_OUT("in SemanticParsing: url = %s ", url.c_str());
	string strNlpResult = HttpQuery(url);
	return strNlpResult;
}

size_t write_function(char *ptr, size_t size, size_t nmemb, string* buff) 
{
	if (NULL == buff)
	{
		return 0;
	}

	int len = size * nmemb;
	buff->assign(ptr, len);
	return buff->size();
}

bool SemanticParser::IsValidResult(string& res)
{
	size_t i = 0;
	for (; i < res.size() && ' ' == res[i]; ++i)
	{
	}

	return (i < res.size()) ? ('{' == res[i] || '[' == res[i]) : false;
}

string SemanticParser::HttpQuery(string& url)
{
	string buff;
	
/* INIT */
	CURL* curl = NULL;
	curl = curl_easy_init();
	CURLcode ret = CURLE_OK;

	if (NULL == curl)
	{
		goto Cleanup;
	}

/* SET_OPT */
	curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
	curl_easy_setopt(curl, CURLOPT_TIMEOUT, mTimeOut);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, &buff);  
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_function);  

/* CURL_PERFORM */
	LOG_OUT("url to nlp query is : %s\n", url.c_str());
	ret = curl_easy_perform(curl);

	if (CURLE_OK != ret)
	{
		LOG_ERR("ret = : %d\n", ret);
	}

	switch(ret)
	{
		case CURLE_WRITE_ERROR:
		case CURLE_OK:
			if (!IsValidResult(buff))
			{
				buff = "";
			}
			break;
		case CURLE_COULDNT_CONNECT:
			buff = "";
			break;
		case CURLE_OPERATION_TIMEDOUT:
			buff = "";
			break;
		default:
			buff = "";
			break;
	}

Cleanup:
/* CLEAN_UP */
	if (NULL != curl)
	{
		curl_easy_cleanup(curl);
	}

	return buff;
}

